from flask import Flask, jsonify,request
import mysql.connector
from flask_cors import CORS
import json,os,base64
app= Flask(__name__)
CORS(app)
UPLOAD_FOLDER = 'uploads'
if not os.path.exists(UPLOAD_FOLDER):
    os.makedirs(UPLOAD_FOLDER)
# 配置数据库连接
db_config = {
    'host': 'mysql.sqlpub.com',
    'port': 3306,
    'user': 'ying2007',
    'password': 'neMEJ8NGipbyAENj',
    'database': 'passapp'
}
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def get_combined_md5_from_dict(base64_dict):
    """计算字典中Base64字符串的联合MD5摘要"""
    combined_hash = hashlib.md5()
    
    # 遍历字典中的每个Base64字符串
    for key in sorted(base64_dict.keys()):  # 按键的顺序处理
        base64_str = base64_dict[key]
        if base64_str==[]:continue
        # 解码Base64字符串为二进制数据
        binary_data = base64.b64decode(base64_str)
        # 计算该数据的MD5摘要
        base64_hash = hashlib.md5(binary_data).hexdigest()
        # 将该MD5摘要合并到最终的MD5计算中
        combined_hash.update(base64_hash.encode('utf-8'))
    
    # 返回联合的MD5摘要
    return combined_hash.hexdigest()
# 修改后的后端代码
@app.route('/api/upload/post' ,methods=['POST'])
def upload():
    # 检查是否有文件
    data = request.get_json()
    print(str(data)[:500])
    title=data['title']
    uid=data['userid']
    print(uid)
    text=data["contentText"].split(r'undefined')[1]
    connection = get_db_connection()
    cursor = connection.cursor(dictionary=True)
    cursor.execute("START TRANSACTION;")
    i=0
    z={}
    for file in data['image']:
        i+=1
        bs=file['src'].split('base64,')
        imgdata = base64.b64decode(bs[1])
        z[i]=imgdata
    print(i)
    if i<9:
        for m in range(i,9):
            print('m',m+1)
            z[m+1]='none'
    _md=get_combined_md5_from_dict(z)
    try:
        cursor.execute("INSERT INTO image (i1, i2, i3, i4, i5, i6, i7, i8, i9, md5, uid) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",(z[1],z[2],z[3],z[4],z[5],z[6],z[7],z[8],z[9],_md,uid))
        cursor.execute("INSERT INTO comments (_from) VALUES (%s)",(uid,))
    except Exception as e:
        print(e)
        cursor.execute("ROLLBACK;")
        return {},500
    cursor.execute("COMMIT;")
    cursor.execute("SELECT iid FROM image WHERE uid = %s AND md5=%s;", (uid,_md))
    iid=cursor.fetchall()[0]['iid']
    cursor.execute("SELECT pid FROM comments WHERE _from=%s;", (uid,))
    pid=cursor.fetchall()[0]['pid']
    cursor.execute("START TRANSACTION;")
    try:
        print(type(title), type(text), type(uid), type(iid), type(pid))
        cursor.execute("INSERT INTO post (title,data,_from,image,comments,audit) VALUES (%s,%s,%s,%s,%s,true)",(title,text,uid,iid,pid))
    except Exception as e:
        print(e)
        cursor.execute("ROLLBACK;")
        return {},500
    cursor.execute("COMMIT;")
    cursor.execute("SELECT pid FROM post WHERE _from=%s;", (uid,))
    pids=cursor.fetchall()[0]['pid']
    if iid and pid and pids:
        return jsonify({"message": "上传成功"}), 200
    else:
        cursor.execute("ROLLBACK;")
        return jsonify({"code":500,"message":"数据插入失败"})
# 获取数据库连接
def get_db_connection():
    connection = mysql.connector.connect(**db_config)
    return connection

# 获取所有帖子数据的 API
@app.route('/api/posts', methods=['GET'])
def get_posts():
    connection = get_db_connection()
    cursor = connection.cursor(dictionary=True)  # 使用字典游标，方便返回 JSON 格式
    cursor.execute('SELECT * FROM post')  # 查询所有帖子
    posts = cursor.fetchall()  # 获取所有数据
    post=[]
    for i in posts:
        print(i)
        if i['audit']:
            a={}
            a['pid']=i['pid']
            a['data']=''.join(i['data'].split(r'undefined'))
            a['thumbs']=i['thumbs']#点赞
            a['title']=i['title']
            print(111)
            cursor.execute("SELECT * FROM user WHERE uid = %s;",(i['_from'],))  # 查询对应的用户
            print(222)
            user = cursor.fetchall()  # 获取所有数据
            print('user',user)
            user=user[0]
            a['name']=user['name'] if user['usability'] else '该账号已封禁'
            a['logo']=user['logo'] if user['usability'] else r'https://via.placeholder.com/40'
            post.append(a)

        

    cursor.close()
    connection.close()
    
    return jsonify(post)  # 返回 JSON 格式的帖子数据
class Chat:
    def __init__(self):
        self.chat = [
            {"me": "你好，帮我看看这个问题"},
            {"001": "你好，问题是什么？"},
            {"me": "这是一个关于API的问题"},
            {"001": "好的，能详细描述一下吗？"}
        ]

    def chat_get(self):
        uid = request.args.get("id")
        print(uid)
        # 返回聊天记录
        return jsonify(self.chat)

    def chat_upload(self):
        data = request.get_json()
        msg=data['msg']
        _from=data['from']
        to=data['to']
        print(msg,_from,to)
        if msg:
            self.chat.append({"me": msg})
        return jsonify({"status": "success", "message": "Message uploaded successfully"})
import hashlib
import base64

def check_password(plain_password: str, salt: str, stored_hashed_password: str) -> bool:
    # 将盐值和密码结合
    password_with_salt = plain_password + salt

    # 使用 SHA-256 进行哈希
    hashed_password = hashlib.sha256(password_with_salt.encode('utf-8')).digest()

    # 将哈希结果转换为 Base64 编码
    hashed_password_base64 = base64.b64encode(hashed_password).decode('utf-8')

    # 比较哈希值是否一致
    return hashed_password_base64 == stored_hashed_password
# 创建Chat类的实例
chat_instance = Chat()
@app.route('/api/login', methods=['POST',"GET"])
def login():
    data = request.get_json()
    username=data['username']
    pwd=data['password']
    connection = get_db_connection()
    cursor = connection.cursor(dictionary=True)  # 使用字典游标，方便返回 JSON 格式
    cursor.execute(f"SELECT * FROM user WHERE name='{username}'")
    friends = cursor.fetchall()[0]
    pwd_s=friends['password']
    salt=friends['salt']
    if check_password(pwd,salt,pwd_s):
        print("登陆成功")
        return jsonify({"id":friends['uid'],'success':True})
    else:
        print("登陆失败",pwd,pwd_s,salt)
        return jsonify({"success":False})
    
    print(data)
# 路由绑定到实例方法
@app.route('/api/chat/get', methods=['GET'])
def chat_get():
    return chat_instance.chat_get()
@app.route('/api/get_user', methods=['GET'])
def get_user():
    uid = request.args.get("uid")
    connection = get_db_connection()
    cursor = connection.cursor(dictionary=True)
    cursor.execute('SELECT * FROM user WHERE uid='+uid)
    user=cursor.fetchall()[0]
    data={
    "status": "success",
    "data": {
        "uid": uid,
        "username":user['name'],
        "image":user['logo'],
        "email": user['mail'], 
        "phone":user['phone']
    },
    "message": "" }
    return jsonify(data)
@app.route('/api/chat/upload', methods=['POST',"GET"])
def chat_upload():
    return chat_instance.chat_upload()
@app.route('/api/chat/list', methods=['POST',"GET"])
def chat_list():
    mid = request.values.get("mid")
    connection = get_db_connection()
    cursor = connection.cursor(dictionary=True)  # 使用字典游标，方便返回 JSON 格式
    cursor.execute('SELECT * FROM friends WHERE uid='+mid)  # 查询
    friends = cursor.fetchall()[0]['friends'].split(",")  # 获取所有数据
    data=[]
    for i in friends:
        if i:
            print(i)
            cursor.execute('SELECT * FROM user WHERE uid='+i)
            user=cursor.fetchall()[0]
            data.append({'name':user['name'],'uid':i,'email':user['mail']})
    cursor.close()
    connection.close()
    return jsonify(data)  # 返回 JSON 格式的帖子数据
@app.route('/api/register', methods=['POST',"GET"])
def register():
    data = request.get_json()  # 获取 JSON 数据
    username = data.get("username")
    password = data.get("password")
    salt=data.get("salt")
    print(password,salt)
    hashed_password = hashlib.sha256((password+salt).encode('utf-8')).digest()
    hashed_password_base64 = base64.b64encode(hashed_password).decode('utf-8')
    mail = data.get("mail")
    print(username,password,salt,hashed_password_base64,mail)
    connection = get_db_connection()
    cursor = connection.cursor(dictionary=True)
    cursor.execute("START TRANSACTION;")
    query = """
    INSERT INTO user (name, password, logo, phone, mail, salt)
    VALUES (%s, %s, 101, 'none', %s, %s)
    """
    data = (username, hashed_password_base64, mail, salt)

    cursor.execute(query, data)
    cursor.execute("COMMIT;")
    cursor.execute(f"SELECT * FROM user WHERE password ='{hashed_password_base64}' ;")
    aaa=cursor.fetchall()[0]["salt"]
    if aaa:
        return jsonify({"code":200})
    else:
        print(aaa,salt)
        cursor.execute("ROLLBACK;")
        return jsonify({"code":500,"msg":"数据插入失败"})
# 错误处理中间件
@app.errorhandler(500)
def internal_error(error):
    return jsonify({"code": 500, "msg": "服务器错误！"}), 500
@app.route('/rr', methods=['POST',"GET"])
def rr():
    sql="""
SET SESSION GROUP_CONCAT_MAX_LEN = 32768;  -- 增加最大长度限制
SELECT GROUP_CONCAT('KILL ', id) 
INTO @kill_cmds
FROM information_schema.processlist
WHERE id != CONNECTION_ID();

PREPARE stmt FROM @kill_cmds;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
"""
    connection = get_db_connection()
    cursor = connection.cursor(dictionary=True)
    cursor.execute(sql) 
    return ""
# 启动 Flask 服务器，监听端口 8080
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)